package com.chennan.common.domian;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @param <E>
 */
@Data
public class PageInfo<E> implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final int PAGE_SIZE = 15;

    /**
     * 内部使用的
     */
    @JsonIgnore
    private int offset;
    private int total;
    private List<E> items;

    /**
     * 目标页页码（前端传）
     */
    private int pageNum;
    /**
     * 每页条数（前端传）
     */
    private int pageSize;

    /**
     * 前一次查询页页码（前端传）
     */
    @JsonIgnore
    private int prePageNum;
    /**
     * 前一次查询页第一条数据的id（前端传）
     */
    @JsonIgnore
    private long prePageFirstId;

    /**
     * 页面顺序
     */
    @JsonIgnore
    private PageSortEnum pageSort;

    /**
     * id顺序
     */
    @JsonIgnore
    private PageSortEnum idSort;

    /**
     * 大于小于号
     */
    @JsonIgnore
    private String compareSign;

    /**
     * map struct 需要
     */
    public PageInfo() {

    }

    public PageInfo(Integer pageNum, Integer pageSize) {
        this.pageNum = (pageNum == null || pageNum < 1 ? 1 : pageNum);
        this.pageSize = (pageSize == null || pageSize < 1 ? PAGE_SIZE : pageSize);
        this.offset = (this.pageNum - 1) * this.pageSize;
    }

    public PageInfo(Integer pageNum, Integer pageSize, Integer prePageNum, Long prePageFirstId, PageSortEnum pageSort) {
        this.pageNum = (pageNum == null || pageNum < 1 ? 1 : pageNum);
        this.pageSize = (pageSize == null || pageSize < 1 ? PAGE_SIZE : pageSize);
        this.pageSort = pageSort;
        if(prePageNum != null && prePageFirstId != null && prePageNum > 0 && prePageFirstId > 0) {
            this.prePageNum = prePageNum;
            this.prePageFirstId = prePageFirstId;
            int pageNumOffset = this.pageNum - this.prePageNum;
            if (this.pageSort.equals(PageSortEnum.ASC)) {
                if (pageNumOffset == 0) {
                    this.compareSign = ">=";
                    this.idSort = PageSortEnum.ASC;
                } else if (pageNumOffset > 0) {
                    this.compareSign = ">=";
                    this.idSort = PageSortEnum.ASC;
                } else {
                    //反向取数据少跳一页（不需要当前页偏移）
                    pageNumOffset++;
                    this.compareSign = "<";
                    this.idSort = PageSortEnum.DESC;
                }
            } else {
                if (pageNumOffset == 0) {
                    this.compareSign = "<=";
                    this.idSort = PageSortEnum.DESC;
                } else if (pageNumOffset > 0) {
                    this.compareSign = "<=";
                    this.idSort = PageSortEnum.DESC;
                } else {
                    //反向取数据少跳一页（不需要当前页偏移）
                    pageNumOffset++;
                    this.compareSign = ">";
                    this.idSort = PageSortEnum.ASC;
                }
            }
            this.offset = (pageNumOffset > 0 ? pageNumOffset : (-1) * pageNumOffset) * this.pageSize;
        }
        else{
            this.prePageNum = 0;
            this.prePageFirstId = 0L;
            this.compareSign = ">";
            this.idSort = this.pageSort;
            this.offset = (this.pageNum - 1) * this.pageSize;
        }
    }

    /**
     * <p>
     * Description: 正常分页使用此变量
     * </p>
     *
     * @return
     */
    public int getOffset() {
        if (this.offset >= this.total) {
            //最后一页的数量
            int pageNumEndCount = this.total % this.pageSize;
            //总页数
            int pageNumTotal = (this.total / this.pageSize) + (pageNumEndCount > 0 ? 1 : 0);
            return ((pageNumTotal < 1 ? 1 : pageNumTotal) - 1) * this.pageSize;
        }

        return this.offset;
    }

    public void setTotal(int value) {
        this.total = value;
        if(this.prePageNum > 0 && this.prePageFirstId > 0) {
            //最后一页的数量
            int pageNumEndCount = this.total % this.pageSize;
            //总页数
            int pageNumTotal = (this.total / this.pageSize) + (pageNumEndCount > 0 ? 1 : 0);
            //相对于前一次查询的偏移页数
            int pageNumToPreOffset = Math.abs(this.pageNum - this.prePageNum);
            //相对于尾页的偏移页数
            int pageNumToEndOffset = Math.abs(pageNumTotal - this.pageNum);
            //当相对前一次查询页的偏移大于相对于首页的偏移，则使用相对于首页的偏移
            if (pageNumToPreOffset > this.pageNum) {
                this.offset = (this.pageNum - 1) * this.pageSize;
                this.prePageFirstId = 0L;
                this.compareSign = ">";
                this.idSort = this.pageSort;
            }
            //当相对前一次查询页的偏移大于相对于尾页的偏移，则使用相对于尾页的偏移
            if (pageNumToPreOffset > pageNumToEndOffset) {
                if (pageNumToEndOffset > 0) {
                    this.offset = (pageNumToEndOffset - 1) * pageSize + (pageNumEndCount > 0 ? pageNumEndCount : this.pageSize);
                } else {
                    this.offset = 0;
                    this.pageSize = pageNumEndCount > 0 ? pageNumEndCount : this.pageSize;
                }
                this.prePageFirstId = 0L;
                this.compareSign = ">";
                this.idSort = this.pageSort.equals(PageSortEnum.ASC) ? PageSortEnum.DESC : PageSortEnum.ASC;
            }
        }
    }

    /**
     * <p>
     * Description: 分页-加载更多时使用此变量
     * </p>
     * 
     * @author zhanghua
     * @return
     */
    public int getOrgOffset() {
        return this.offset;
    }

    public List<E> getItems() {
        if (items == null)
            items = new ArrayList<>();
        return items;
    }

    public static void main(String[] args) {

        //正序
        PageInfo<Long> pageInfo = new PageInfo<>(10,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(11,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(12,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(18,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(18,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(9800);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(9,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(8,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(2,500,10,4501L, PageSortEnum.ASC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        //倒序
        pageInfo = new PageInfo<>(10,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(11,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(12,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(18,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(9,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(8,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(2,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(10000);
        System.out.println(pageInfo);
        pageInfo = new PageInfo<>(20,500,10,4501L, PageSortEnum.DESC);
        pageInfo.setTotal(9800);
        System.out.println(pageInfo);
    }

}
